﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using MvcSystemsCommander.Extensions.Security;
using MvcSystemsCommander.Models.Entity;
using MvcSystemsCommander.Models.Repository;

namespace MvcSystemsCommander.Models.Service
{
    public class WinAuthModel
    {
        public string Domain { get; set; }
        public string Username { get; set; }

        public WinAuthModel(string nWinString)
        {
            string[] splits = nWinString.Split("\\".ToCharArray());
            this.Domain = splits[0];
            this.Username = splits[1];
        }
    }

    public class AuthenticationService : IService
    {
        private IGenericService<User> _UserService;
        private IGenericService<Identity> _IdentityService;
        private IGenericService<Role> _RoleService;

        public AuthenticationService()
        {
            this._UserService = new UserService();
            this._IdentityService = new IdentityService();
            this._RoleService = new RoleService();
        }

        public string UsernameForWindowsAuthIdentity(string nWinName)
        {
            WinAuthModel wAuth = new WinAuthModel(nWinName);

            WindowsIdentity i = _IdentityService.ServiceRepository.Query()
                .OfType<WindowsIdentity>()
                .Where(x => x.Domain.Equals(wAuth.Domain) && x.Username.Equals(wAuth.Username)).FirstOrDefault();

            if (i != null) { return i.User.Username; }
            else { return null; }
        }

        public bool ValidateApplicationUser(string nUsername, string nPassword)
        {
            bool validated = false;
            AppIdentity i = _IdentityService.ServiceRepository.Query()
                .OfType<AppIdentity>()
                .Where(x => x.Username == nUsername).FirstOrDefault();

            if (i != null)
            {
                validated = HashwordHelper.Compare(nPassword, i.Salt, i.Hashword);
            }

            return validated;
        }

        public string[] AuthorizedRoles(string nUsername)
        {
            User user = _UserService.ServiceRepository.Query().Where(x => x.Username.Equals(nUsername)).FirstOrDefault();
            string[] roles = _RoleService.ServiceRepository.Query()
                .Where(x => x.Users.Contains(user))
                .Select(r => r.Name)
                .ToArray();

            return roles;
        }

        public bool IsUserInRole(string nUsername, string nRole)
        {
            User user = _UserService.ServiceRepository.Query().FirstOrDefault(u => u.Username.Equals(nUsername, StringComparison.CurrentCultureIgnoreCase));

            return user.Roles.Any(r => r.Name.Equals(nRole, StringComparison.CurrentCultureIgnoreCase));
                
        }
    }
}